/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.ac.iie.di.ocr.util;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;

/**
 *
 * @author root
 */
public class FtpTools {
    
    private static Logger logger = Logger.getLogger(FtpTools.class);
    
    public static void main(String[] args) {
        String file = "/home/jr/groupmsg/pam_1_19_text.20170523172100.log";
        System.out.println(file.substring(file.lastIndexOf("/") + 1, file.length()));
        
        FtpTools ftpTools = new FtpTools();
        ftpTools.downDataFile(ftpTools.createFtpClient("192.168.11.96", 21, "qinjia", "qinjia"), "192.168.11.96", "666", "C:\\Users\\Austin\\Desktop", "ssssssss.log", 1800);
    }
    
    public Boolean downFile(String url, int port, String username, String password, String remotePath, String localPath) {
        List downloadFile = new ArrayList<String>();
        boolean success = false;
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.connect(url, port);
//            ftp.connect(url);
            //如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.login(username, password);//登录
            ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
            reply = ftp.getReplyCode();
            logger.info(url + " reply: " + reply);
            if (!FTPReply.isPositiveCompletion(reply)) {
                logger.info(url + " if (!FTPReply.isPositiveCompletion(reply)) {");
                ftp.disconnect();
                logger.info(url + " ftp login err!username=" + username + ",password=" + password);
                return success;
            }
            
            ftp.enterLocalPassiveMode();//在linux上，由于安全限制，可能某些端口没有开启，所以就出现阻塞.开通一个端口来传输数据
            boolean activeFlag = false;
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            boolean changeWorkingDirectory = ftp.changeWorkingDirectory(remotePath); //转移到FTP服务器目录
            logger.debug(url + " 切换目录：" + changeWorkingDirectory + " ,下载路径：" + remotePath);
            try {
                FTPFile[] fs0 = ftp.listFiles();
//                logger.info(url + "  path :" + remotePath + " ftp list size is " + fs0.length);
                List fileName = new ArrayList<String>();
                for (FTPFile f : fs0) {
                    fileName.add(f.getName());
                }
                Long startTime = System.currentTimeMillis();
                Long fileSize = 0L;
                for (FTPFile f : fs0) {
                    OutputStream is = null;
                    try {
                        File rootDir = new File(localPath);
                        if (!rootDir.exists()) {
                            rootDir.mkdirs();
                        }
                        if (!f.getName().endsWith(".log")) {
                            continue;
                        }
                        //标志正在传输 
                        if (f.getName().endsWith(".temp")) {
                            continue;
                        }
                        
                        File localFile = new File(localPath + File.separator + f.getName());
                        is = new FileOutputStream(localFile);
                        boolean retrieveFile = ftp.retrieveFile(f.getName(), is);
                        if (retrieveFile) {
                            fileSize += localFile.length();
                            File newFile = new File(GlobalParameters.TMP_GWX);
                            FileUtils.copyFileToDirectory(localFile, newFile, true);
                            FileUtils.deleteQuietly(localFile);
                            downloadFile.add(f.getName());
                            success = true;
                        } else {
                            logger.info(url + " " + f.getName() + " download error! Retry");
                            boolean fl = ftp.retrieveFile(f.getName(), is);
                            logger.info(url + " " + f.getName() + " download return " + fl + " !");
                            if (fl) {
                                fileSize += localFile.length();
                                File newFile = new File(GlobalParameters.TMP_GWX);
                                FileUtils.copyFileToDirectory(localFile, newFile, true);
                                FileUtils.deleteQuietly(localFile);
                                downloadFile.add(f.getName());
                                success = true;
                            } else {
                                success = false;
                            }
                        }
//                        logger.info(url + " " + f.getName() + " download sucess!");
                    } catch (Exception ex) {
                        logger.error(url + " " + f.getName() + " download err!" + ex.getMessage(), ex);
                    } finally {
                        if (is != null) {
                            try {
                                is.close();
                            } catch (Exception e) {
                            }
                        }
                    }
                }
                Long endTime = System.currentTimeMillis();
                logger.info("downTime is " + (endTime - startTime) + " downFile is " + fileName.size() + "downFile Size " + fileSize);
            } catch (Exception e) {
                logger.error(url + " ftp.listFiles error. " + e.getMessage(), e);
                activeFlag = true;
            } finally {
                if (activeFlag) {
                    ftp.enterLocalActiveMode();
//                    ftp.enterLocalPassiveMode();//在linux上，由于安全限制，可能某些端口没有开启，所以就出现阻塞.开通一个端口来传输数据
                    logger.info(url + " current getDataConnectionMode: " + ftp.getDataConnectionMode());
                }
            }
            ftp.logout();
        } catch (Exception e) {
            logger.error(url + " ftp download err " + e.getMessage(), e);
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                    logger.error(url + " " + ioe.getMessage(), ioe);
                }
            }
        }
        logger.info(url + " ftp download finish!");
        return success;
    }
    
    public boolean downDataFile(FTPClient ftp, String url, String remotePath, String localPath, String file, int timeout) {
//        if (file.startsWith(File.separator)) {
//            file = file.substring(1, file.length());
//        }
//        localPath = localPath + File.separator;
        boolean success = false;
        try {
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            ftp.setDataTimeout(timeout * 1000);
            boolean changeWorkingDirectory = ftp.changeWorkingDirectory(remotePath); //转移到FTP服务器目录
            logger.info("切换目录：" + changeWorkingDirectory + " ,下载路径：" + remotePath);
            OutputStream is = null;
            try {
                File rootDir = new File(localPath);
                if (!rootDir.exists()) {
                    rootDir.mkdirs();
                }
                Long startTime = System.currentTimeMillis();
                File localFile = new File(localPath + File.separator + file);
                is = new FileOutputStream(localFile);
                boolean retrieveFile = false;
                while (!ftp.retrieveFile(file, is)) {
                    logger.info("downfile " + localFile.getPath() + " retry!");
                }
                retrieveFile = true;
                if (retrieveFile) {
                    logger.info(url + " " + file + " download sucess!");
                    File newFile = new File(GlobalParameters.TMP_GWX);
                    FileUtils.copyFileToDirectory(localFile, newFile, true);
                    FileUtils.deleteQuietly(localFile);
                    Long endTime = System.currentTimeMillis();
                    logger.info("downTime is " + (endTime - startTime) + " downFile is " + file + "downFile Size " + localFile.length());
                    success = true;
                } else {
                    logger.info(url + " " + file + " download error! Retry" + localFile.getPath() + "xxxxxxxxx" + file);
                    boolean fl = ftp.retrieveFile(file.substring(file.lastIndexOf(File.separator) + 1, file.length()), is);
                    logger.info(url + " " + file + " download return " + fl + " !");
                }
            } catch (Exception ex) {
                logger.error(url + " " + file + " download err! and ftp " + ftp + " " + ex, ex);
            } finally {
                if (is != null) {
                    try {
                        is.flush();
                        is.close();
                    } catch (Exception e) {
                    }
                }
            }
        } catch (Exception e) {
            logger.error(url + " ftp download err " + file + " " + e.getMessage(), e);
        }
        logger.info(url + " ftp download finish!");
        return success;
    }
    
    public boolean deleteFile(FTPClient ftp, String url, String remotePath, String file, int timeout) {
//        if (file.startsWith(File.separator)) {
//            file = file.substring(1, file.length());
//        }
        boolean success = false;
        try {
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            ftp.setDataTimeout(timeout * 1000);
            boolean changeWorkingDirectory = ftp.changeWorkingDirectory(remotePath); //转移到FTP服务器目录
            logger.info("切换目录：" + changeWorkingDirectory + " ,下载路径：" + remotePath);

//            logger.debug(url + " 切换目录：" + changeWorkingDirectory + " ,上传路径：" + remotePath);
            if (!changeWorkingDirectory) {
                ftp.logout();
                ftp.disconnect();
                logger.info(url + " ftp changeWorkingDirectory failed.");
                return success;
            }
            try {
//                    logger.debug(url + " delete file");
                //upload dwd file
                boolean flag = false;
                while (!ftp.deleteFile(file)) {
                    logger.info("deletefile " + file + " retry!");
                    FTPFile[] fs0 = ftp.listFiles();
                    for (FTPFile f : fs0) {
                        if (file.equals(f.getName())) {
                            logger.info(url + " " + file + "  " + " delete sucess!");
                            return true;
                        }
                    }
                    FtpTools ft = new FtpTools();
                    ftp = ft.createFtpClient(url, 21, "jr", "111111");
                }
                flag = true;
                if (flag) {
                    success = true;
                }
                logger.info(url + " " + file + "  " + " delete sucess!");
            } catch (Exception ex) {
                logger.error(url + " " + remotePath + " " + file + " delete err!" + ex.getMessage(), ex);
            } finally {
            }
            
            ftp.logout();
        } catch (Exception e) {
            logger.error(url + " ftp delete err " + file + " " + e.getMessage(), e);
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                    logger.error(url + " " + ioe.getMessage(), ioe);
                }
            }
        }
        return success;
    }
    
    public boolean deleteFileO(FTPClient ftp, String url, String remotePath, String file, int timeout) {
        if (file.startsWith(File.separator)) {
            file = file.substring(1, file.length());
        }
        boolean success = false;
        try {
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            ftp.setDataTimeout(timeout * 1000);
            boolean changeWorkingDirectory = ftp.changeWorkingDirectory(remotePath); //转移到FTP服务器目录
            logger.info("切换目录：" + changeWorkingDirectory + " ,下载路径：" + remotePath);

//            logger.debug(url + " 切换目录：" + changeWorkingDirectory + " ,上传路径：" + remotePath);
            if (!changeWorkingDirectory) {
                ftp.logout();
                ftp.disconnect();
                logger.info(url + " ftp changeWorkingDirectory failed.");
                return success;
            }
            try {
//                    logger.debug(url + " delete file");
                //upload dwd file
                boolean flag = ftp.deleteFile(file.substring(file.lastIndexOf(File.separator) + 1, file.length()));
                
                if (flag) {
                    success = true;
                } else {
                    logger.info(url + " " + file + "  " + " delete error! Retry");
                    boolean fl = ftp.deleteFile(file.substring(file.lastIndexOf(File.separator) + 1, file.length()));
//                        logger.info(url + " " + fileName + "  " + " delete return " + fl + "!");
                    if (fl) {
                        success = true;
                    } else {
                        success = false;
                    }
                }
                logger.info(url + " " + file + "  " + " delete sucess!");
            } catch (Exception ex) {
                logger.error(url + " " + remotePath + " delete err!" + ex.getMessage(), ex);
            } finally {
            }
            
            ftp.logout();
        } catch (Exception e) {
            logger.error(url + " ftp delete err " + e.getMessage(), e);
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                    logger.error(url + " " + ioe.getMessage(), ioe);
                }
            }
        }
        return success;
    }
    
    public boolean uploadFile(FTPClient ftp, String url, String remotePath, String file, int timeout) {
//        if (!file.startsWith("/")) {
//            file = "/" + file;
//        }
        boolean success = false;
//        remotePath = remotePath + file.substring(0, file.lastIndexOf("/") + 1);
//        String fileName = file.substring(file.lastIndexOf("/") + 1, file.length());
        while (true) {
            if (ftp == null) {
                FtpTools ft = new FtpTools();
                ftp = ft.createFtpClient(url, 21, "jr", "111111");
                logger.info("ftp is null" + null);
            } else {
                break;
            }
        }
        try {
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            ftp.setDataTimeout(timeout * 1000);
            boolean changeWorkingDirectory = ftp.changeWorkingDirectory(remotePath); //转移到FTP服务器目录
            logger.debug(url + " 切换目录：" + changeWorkingDirectory + " ,上传路径：" + remotePath);
            
            InputStream dwd = null;
            try {
                logger.debug(url + " upload del file");
                dwd = new ByteArrayInputStream("ok".getBytes("utf-8"));
                boolean flag = false;
                while (!ftp.storeFile(file + ".del", dwd)) {
                    logger.info(url + " " + file + ".del upload error! Retry");
                    FTPFile[] fs0 = ftp.listFiles();
                    for (FTPFile f : fs0) {
                        if (file.equals(f.getName())) {
                            logger.info(url + " " + file + ".del " + " upload sucess!");
                            return true;
                        }
                    }
                    FtpTools ft = new FtpTools();
//                    ftp = ft.createFtpClient(url, 21, "jr", "111111");
                }
                if (flag) {
                    logger.debug(url + " " + file + ".del upload sucess!");
                    success = true;
                }
            } catch (Exception ex) {
                logger.error(url + " " + file + ".del upload err!" + ex.getMessage(), ex);
            } finally {
                if (dwd != null) {
                    try {
                        dwd.close();
                    } catch (Exception e) {
                    }
                }
            }
        } catch (Exception e) {
            logger.error(url + " " + file + "ftp upload err " + e.getMessage(), e);
        }
        return success;
    }
    
    public FTPClient createFtpClient(String url, int port, String username, String password) {
        logger.info(url + " begin to create ftpClient. and the ip is " + url + ",port is " + port + ",username is " + ",password is " + password);
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            logger.debug(url + " begin to connect FTPClient.");
            ftp.connect(url, port);
            logger.debug(url + " connect ftp successfulley. And begin to login.");
            //如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.login(username, password);//登录
            logger.debug(url + " login FTP successfully.");
            reply = ftp.getReplyCode();
            logger.info("replyreplyreplyreplyreply" + reply);
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                logger.info(url + " " + url + "ftp login err!username=" + username + ",password=" + password);
                return null;
            }
            logger.info(url + " create ftpClient successfully.");
        } catch (Exception e) {
            logger.error(e.getMessage() + e);
            return null;
        }
        return ftp;
    }
    
    public void destroyFtpClient(FTPClient ftpClient) {
        try {
            if (ftpClient != null && ftpClient.isConnected()) {
                ftpClient.logout();
            }
        } catch (Exception e) {
            logger.error(" ftp client logout failed." + e.getMessage(), e);
        } finally {
            if (ftpClient != null) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ex) {
                    logger.error(" ftp client disconnect failed." + ex.getMessage(), ex);
                }
            }
        }
    }
    
    public String downDataFile1(FTPClient ftp, String url, String remotePath, String localPath, String file) {
        
        localPath = localPath + File.separator + file.substring(0, file.lastIndexOf("/") + 1);
        String success = "false";
        try {
//            logger.debug(url + " current getDataConnectionMode: " + ftp.getDataConnectionMode());
//            //设置为主动
//            ftp.enterLocalActiveMode();
//            logger.debug(url + " current getDataConnectionMode: " + ftp.getDataConnectionMode());
//            boolean activeFlag = false;
//            try {
//                FTPFile[] fs0 = ftp.listFiles();
//                logger.debug(url + " ftp list size is " + fs0.length);
//            } catch (Exception e) {
//                logger.error(url + " ftp.listFiles error. " + e.getMessage(), e);
//                activeFlag = true;
//            } finally {
//                if (activeFlag) {
//            ftp.enterLocalPassiveMode();//在linux上，由于安全限制，可能某些端口没有开启，所以就出现阻塞.开通一个端口来传输数据
//                    logger.debug(url + " current getDataConnectionMode: " + ftp.getDataConnectionMode());
//                }
//            }
//            ftp.setDataTimeout(1);//ms
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            String printWorkingDirectory = ftp.printWorkingDirectory();
            logger.debug(url + " 当前工作路径 " + printWorkingDirectory);
            if (!printWorkingDirectory.endsWith(remotePath)) {
                boolean changeWorkingDirectory = ftp.changeWorkingDirectory(remotePath); //转移到FTP服务器目录
                logger.debug("切换目录：" + changeWorkingDirectory + " ,下载路径：" + remotePath);
            }
            
            OutputStream is = null;
            try {
                File rootDir = new File(localPath);
                if (!rootDir.exists()) {
                    rootDir.mkdirs();
                }
                File localFile = new File(localPath + file.substring(file.lastIndexOf("/") + 1, file.length()));
                is = new FileOutputStream(localFile);
                System.out.println("xia zai ");
                boolean retrieveFile = ftp.retrieveFile(file, is);
                System.out.println("hhh");
                if (retrieveFile) {
                    logger.debug(url + " " + file + " download sucess!");
                    success = "true";
                } else {
                    logger.debug(url + " " + file + " download error! Retry");
                    boolean fl = ftp.retrieveFile(file, is);
                    logger.debug(url + " " + file + " download return " + fl + " !");
                    if (fl) {
                        success = "true";
                    } else {
                        logger.debug(url + " " + file + " download error! Retry,Retry");
                        boolean f2 = ftp.retrieveFile(file, is);
                        logger.debug(url + " " + file + " download return " + f2 + " !");
                        if (f2) {
                            success = "true";
                        } else {
                            success = "false";
                        }
                    }
                }
            } catch (Exception ex) {
                logger.error(file + " download err!" + ex.getMessage(), ex);
                success = "ERROR";
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (Exception e) {
                    }
                }
            }
        } catch (Exception e) {
            logger.error(url + " ftp download err " + e.getMessage(), e);
        }
        logger.debug(url + " ftp download finish!");
//        boolean available = ftp.isAvailable();
//        boolean connected = ftp.isConnected();
//        System.out.println(available);
//        System.out.println(connected);
//        try {
//            ftp.sendCommand("pwd");
//        } catch (IOException ex) {
//            java.util.logging.Logger.getLogger(FtpTools.class.getName()).log(Level.SEVERE, null, ex);
//        }
//        boolean remoteVerificationEnabled = ftp.isRemoteVerificationEnabled();
//        System.out.println("gggggggggg" + remoteVerificationEnabled);

        return success;
    }
    
}
